import time
import itertools
from collections import defaultdict
ALL_Time=time.time()
def read_config(file_path):
    config = {
        'max_combinations': 100,
        'timeout_limit': 2,
        'max_diff_limit': 3,
        'min_diff_limit': 1
    }
    with open(file_path, 'r') as file:
        for line in file:
            if line == "\n":
                continue
            if "#" in line:
                continue
            key, value = line.strip().split('=')
            if key in config:
                config[key] = int(value)
        print("=============")
        print("配置读取成功！")
        print("=============")
    return config

def read_numbers_from_file(file_path):
    numbers = []
    with open(file_path, 'r') as file:
        for line in file:
            try:
                # 尝试将行转换为浮点数
                number = float(line.strip())
                numbers.append(number)
            except ValueError:
                # 如果转换失败，跳过当前行
                continue
    return numbers

def expand_numbers_based_on_divisibility(numbers, target):
    expanded_numbers = []
    numbers = list(set(numbers))
    for number in numbers:
        temp_target = target
        while True:
            if(temp_target - number >= 0):
                expanded_numbers.append(number)
                temp_target -= number
            else:
                break
    return expanded_numbers


def find_compatible_combinations(numbers, target, config):
    combinations = []  # 存储找到的符合条件的组合
    expanded_numbers = expand_numbers_based_on_divisibility(numbers, target)
    seen_combinations = set()  # 用于去重的集合
    timed_out_numbers = set()  # 存储处理超时的数字
    total_numbers = len(expanded_numbers)
    processed_numbers = 0

    def JDT():
        current_progress = int((processed_numbers / total_numbers) * 100)  # 当前进度百分比
        # 每处理20%的数字，输出一次进度
        if current_progress % 5 == 0 and current_progress not in progress_reported:
            print(f"处理进度: {current_progress}%  当前组合数：{len(combinations)}")
            progress_reported.add(current_progress)

    for number in expanded_numbers:
        JDT()
        
        #达到最大组合数
        if len(combinations) >= config['max_combinations']:
            break
        
            
        # 检查当前数字是否已超时，如果是，则跳过
        if number in timed_out_numbers:
            JDT()
            continue
        
        start_time = time.time()

        for r in range(1, len(expanded_numbers) + 1):

            JDT()
            
            #达到最大组合数
            if len(combinations) >= config['max_combinations']:
                break
            
            if time.time() - start_time > config['timeout_limit']:
                print(f"【超时】尝试超过{config['timeout_limit']}秒，跳过数字 {number}")
                timed_out_numbers.add(number)  # 记录超时的数字
                break

            
            for combination in set(itertools.combinations([number] + expanded_numbers, r)):
                JDT()      
                
                if time.time() - start_time > config['timeout_limit']:
                    timed_out_numbers.add(number)  # 记录超时的数字
                    print(f"【超时】尝试超过{config['timeout_limit']}秒，跳过数字 {number}")
                    break

                sorted_combination = tuple(sorted(combination))
                if sorted_combination in seen_combinations:
                    continue

                result = sum(sorted_combination)
                if result <= target:
                    diff = abs(target - result)
                    if config['min_diff_limit'] <= diff <= config['max_diff_limit']:
                        combinations.append((sorted_combination, result, '相加', diff))
                        seen_combinations.add(sorted_combination)
                        if len(combinations) >= config['max_combinations']:
                            print("【提前结束】当前已达到最大组合数，若缺少数据请增大最大组合数，增加超时数值！")
                            break
    

                    
            print(f"{number} 已计算组合：{len(set(itertools.combinations([number] + expanded_numbers, r)))}")

        processed_numbers += 1
    
    JDT()
    sorted_combinations = sorted(combinations, key=lambda x: x[3])
    return sorted_combinations


if __name__ == "__main__":
    try:
        target = int(input("请输入一个目标值（不输入则为默认1250）："))
    except ValueError:
        target = 1250

    config = read_config('./config.txt')
    file_path = './num.txt'
    numbers = read_numbers_from_file(file_path)

    global progress_reported
    progress_reported = set()  # 用来记录已经报告的进度
    
    combinations = find_compatible_combinations(numbers, target, config)

    groups = defaultdict(list)
    for combo in combinations:
        key = (combo[1], combo[3])
        groups[key].append(combo[0])

    with open("new_num.txt", "w") as f:
        f.write("以差距正序输出的组合，最多{}组，差距在{}至{}之间:\n".format(
            config['max_combinations'], config['min_diff_limit'], config['max_diff_limit']))
        for (total, diff), combos in groups.items():
            f.write("总值: {}  差距: {}:\n".format(total, diff))
            for combo in combos:
                f.write("  {}\n".format(combo))
            f.write("\n")
print("处理进度: 100%")
print("=============")
ALL_Time=time.time()-ALL_Time
print("输出完成~ 总耗时：%.2f秒"%ALL_Time)
input("按enter退出~")
